#include <gdt.h>

void gdtEncodeEntry(unsigned char *target, const GDTSegmentDescriptor * source) {
	// Check the limit to make sure that it can be encoded
	if ((source->limit > 65536) && (source->limit & 0xFFF) != 0xFFF) {
	//	kerror("You can't do that!");
	}

	unsigned int limit = source->limit;
	if (limit > 65536) {
		// Adjust granularity if required
		limit >>= 12;
		target[6] = 0xC0;
	}
	else {
		target[6] = 0x40;
	}
	// Encode the limit
	target[0] = limit & 0xFF;
	target[1] = (limit >> 8) & 0xFF;
	target[6] |= (limit >> 16) & 0xF;
	// Encode the base 
	target[2] = source->base & 0xFF;
	target[3] = (source->base >> 8) & 0xFF;
	target[4] = (source->base >> 16) & 0xFF;
	target[7] = (source->base >> 24) & 0xFF;
	// And... Type
	target[5] = source->type;
}

void gdtMakeOneSegmentTable(void * target, unsigned int base) {
	GDTSegmentDescriptor descriptor0 = { 0, 0, 0 };
	GDTSegmentDescriptor descriptor1 = { 0, 0x100000, 0b10010010 }; // 200K rw data segment.

	gdtEncodeEntry((unsigned char *) (target + sizeof(GDTRegister)), &descriptor0);
	gdtEncodeEntry((unsigned char *) (target + sizeof(GDTRegister)) + sizeof(GDTSegmentDescriptor),
			&descriptor1);

	GDTRegister * gdtr = (GDTRegister *) target;
	gdtr->limit = 2 * sizeof(GDTSegmentDescriptor) - 1;
	gdtr->base = base;
}

void fillGdt(void) {
	
}

